package top.z.orm.handle.logging;

import top.z.orm.core.logging.Log;
import top.z.orm.handle.file.FileHandle;
import top.z.orm.handle.osql.core.CoreConfig;
import top.z.orm.handle.osql.util.DateUtil;

import java.io.File;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.text.SimpleDateFormat;

public class FileLogger implements Log {

    private       String clazz          = null;
    // 换行符
    private final String LINE_SEPARATOR = System.getProperty("line.separator");

    private static final String TRACE = "TRACE";
    private static final String DEBUG = "DEBUG";
    private static final String INFO  = "INFO";
    private static final String WARN  = "WARN";
    private static final String ERROR = "ERROR";
    private static final String SPACE = " ";
    private static final String LEFT  = "[";
    private static final String RIGHT = "]";

    public FileLogger() {
    }

    public FileLogger(String clazz) {
        this.clazz = clazz;
    }

    @Override
    public boolean isTraceEnabled() {
        return true;
    }

    @Override
    public void trace(String msg) {
        if (this.clazz != null) {
            print(TRACE, msg, clazz);
        } else {
            print(TRACE, msg, null);
        }
    }

    @Override
    public boolean isDebugEnabled() {
        return true;
    }

    @Override
    public void debug(String msg) {
        if (this.clazz != null) {
            print(DEBUG, msg, clazz);
        } else {
            print(DEBUG, msg, null);
        }
    }

    @Override
    public void debug(String msg, Throwable t) {
        if (this.clazz != null) {
            print(DEBUG, msg + LINE_SEPARATOR + t.getMessage(), clazz);
        } else {
            print(DEBUG, msg + LINE_SEPARATOR + t.getMessage(), null);
        }
    }

    @Override
    public boolean isInfoEnabled() {
        return true;
    }

    @Override
    public void info(String msg) {
        if (this.clazz != null)
            print(INFO, msg, clazz);
        else
            print(INFO, msg, null);
    }

    @Override
    public boolean isWarnEnabled() {
        return true;
    }

    @Override
    public void warn(String msg) {
        if (this.clazz != null) {
            print(WARN, msg, clazz);
        } else {
            print(WARN, msg, null);
        }
    }

    @Override
    public void warn(String msg, Throwable t) {
        if (this.clazz != null) {
            print(WARN, msg + LINE_SEPARATOR + t.getMessage(), clazz);
        } else {
            print(WARN, msg + LINE_SEPARATOR + t.getMessage(), null);
        }
    }

    @Override
    public boolean isErrorEnabled() {
        return true;
    }

    @Override
    public void error(String msg) {
        if (this.clazz != null) {
            print(ERROR, msg, clazz);
        } else {
            print(ERROR, msg, null);
        }
    }

    @Override
    public void error(String msg, Throwable t) {
        if (this.clazz != null) {
            print(ERROR, msg + LINE_SEPARATOR + t.getMessage(), clazz);
        } else {
            print(ERROR, msg + LINE_SEPARATOR + t.getMessage(), null);
        }
    }

    private void print(String level, String msg, String className) {
        StringBuilder b = new StringBuilder();
        if (CoreConfig.getPrintSqlDate()) {
            b.append(DateUtil.currentDate());
            b.append(SPACE);
        }
        if (CoreConfig.getPrintSqlLevel()) {
            b.append(LEFT).append(level).append(RIGHT).append(SPACE);
        }
        if (null != className && "".equals(className.trim())) {
            b.append(LEFT).append(className).append(RIGHT).append(SPACE);
        }
        b.append(msg);
        appendFile(b.toString());
    }

    private void appendFile(String content) {
        Path logFile = Paths.get(CoreConfig.getLogFilePath());
        if (!Files.exists(logFile)) {
            String datetime = new SimpleDateFormat(CoreConfig.getLogDateFormat()).format(System.currentTimeMillis());
            String path     = System.getProperty("user.dir") + File.separator + "src" + File.separator + "main" + File.separator + "resources" + File.separator + "log" + File.separator + datetime + ".txt";
            System.err.println("[Bee] [WARN] Set the path for FileLogger automatically:  " + path);
        }
        FileHandle.appendFile(logFile.toString(), content);
    }
}